/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0.
 * See `LICENSE` in the project root for license information.
 */

package me.ijleex.mgmt.system.auth.filter;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import me.ijleex.mgmt.framework.entity.Result;
import me.ijleex.mgmt.system.auth.model.JwtUser;
import me.ijleex.mgmt.system.auth.service.IJwtService;

/**
 * Token过滤器.
 *
 * @author liym
 * @since 2020-08-09 11:47 新建
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final String JWT_HEADER = "Authorization";

    private final IJwtService jwtService;

    public JwtAuthenticationFilter(IJwtService jwtService) {
        this.jwtService = jwtService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String token = request.getHeader(JWT_HEADER);
        if (StringUtils.hasLength(token)) {
            Result result = this.jwtService.validateToken(token);
            if (result.isOk() && SecurityContextHolder.getContext().getAuthentication() == null) {
                JwtUser jwtUser = (JwtUser) result.getMsg();
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        chain.doFilter(request, response);
    }

}
